﻿using System;
using System.Collections.Generic;
using System.Linq;
using WorkLogger.Client.DataAccess.Model;
using WorkLogger.Client.DataAccess.Repository;
using WorkLogger.Client.Forms;

namespace WorkLogger.Client.Presenters {
	public class WorkedTimeReportPresenter {
		private readonly IWorkedTimeReportForm reportForm;
		private readonly IWorkDayRepository workDayRepository;
		private readonly ISystemClock systemClock;
		private readonly WorkTimeCalculator workTimeCalculator;
		private readonly AppOptions appOptions;

		public WorkedTimeReportPresenter(IWorkedTimeReportForm reportForm,
		                                 IWorkDayRepository workDayRepository,
		                                 ISystemClock systemClock,
		                                 WorkTimeCalculator workTimeCalculator,
		                                 AppOptions appOptions) {
			this.reportForm = reportForm;
			this.workDayRepository = workDayRepository;
			this.systemClock = systemClock;
			this.workTimeCalculator = workTimeCalculator;
			this.appOptions = appOptions;
			reportForm.BuildReport += ReportFormBuildReport;
		}

		private void ReportFormBuildReport(object sender, EventArgs e) {
			BuildReport();
		}

		private void BuildReport() {
			var report = new WorkedTimeReport();
			IEnumerable<WorkDay> workDays = workDayRepository.GetByPeriod(reportForm.BeginPeriod, reportForm.EndPeriod);
			var reportItems = new List<WorkedTimeReport.WorkDayReportItem>();
			report.TotalWorkedTime = new TimeSpan(0, 0, 0);
			foreach (WorkDay workDay in workDays) {
				TimeSpan workedTime = workTimeCalculator.GetWorkedTime(workDay);
				report.TotalWorkedTime += workedTime;

				decimal income = (appOptions.Salary*(int)workedTime.TotalMinutes)/60;
				if (appOptions.DeductIncomeTax)
					income *= 0.87m;
				report.TotalIncome += income;

				var lunchTime = new TimeSpan(0, 0, 0);

				if (workDay.LunchTimes != null) {
					lunchTime = workDay.LunchTimes.Aggregate(lunchTime,
					                                         (current, lunch) => current + (lunch.EndLunch - lunch.StartLunch));
				}

				reportItems.Add(new WorkedTimeReport.WorkDayReportItem {
				                                                       	WorkDate = workDay.WorkDate.Date,
				                                                       	StartWork = workDay.StartWork.TimeOfDay,
				                                                       	LunchTime = lunchTime,
				                                                       	EndWork = workDay.EndWork.TimeOfDay,
				                                                       	WorkedTime = workedTime,
				                                                       	Income = income
				                                                       });
			}
			report.WorkedDays = reportItems.ToArray();
			reportForm.ShowReport(report);
		}

		public void BuildMonthReport() {
			DateTime now = systemClock.Now;
			reportForm.BeginPeriod = new DateTime(now.Year, now.Month, 1);
			reportForm.EndPeriod = new DateTime(now.Year, now.Month, DateTime.DaysInMonth(now.Year, now.Month));
			BuildReport();
		}
	}
}